import numpy,defacing,sys,cv
from nifti import NiftiImage
import GaborMatchingXV as gm
import VolRender_np as vr
import threading,subprocess
import os
import glob
import numpy as np
from optparse import OptionParser
import Gabor
import cPickle

def myReadFeatures(fname):
    """BEC: Costas' files don't seem to have the necessary line breaks to be read by his program"""
    f = file(fname,"r")
    data = f.read()
    data = data.split()
    numfeatures = int(data.pop(0))
    features = []
    while(True):
        try:
            fn = data.pop(0)
            fx = data.pop(0)
            fy = data.pop(0)
            features.append((fn,fx,fy))
        except IndexError:
            break
    return features


def getParser():

    parser = OptionParser()
    parser.add_option("-f", "--filename",dest= "filename",type = "string", default="")
    parser.add_option("-t", "--threshold", dest = "threshold",type = "int",default= 0)
    parser.add_option("-m","--mode",  dest= "mode", type = "string",default= "")
    parser.add_option("-c", "--command", dest = "command", type = "string", default ="")
    
    return parser



def LocateFeatures(dirName,mode,win,isuffix=".png",dsuffix=".data"):
    rdir = "XVResults%d"%win
    if( not os.path.exists(rdir) ):
        os.mkdir(rdir)

    fr = file(os.path.join(rdir,"diffResults_%s.txt"%mode),"w")
    files = glob.glob(os.path.join(dirName,"*"+isuffix))
    

    featureResults = {'right_nouse_lateral':([],[]),'left_nouse_medial':([],[]),'nose_bottom':([],[]),
                    'mouth_right':([],[]),'mouth_center':([],[]),'mouth_left':([],[]),
                    'left_eye_medial':([],[]),'left_eye_lateral':([],[]),
                    'right_eye_lateral':([],[]),'right_eye_lateral':([],[])}

    featureResultsPop = {'right_nouse_lateral':([],[]),'left_nouse_medial':([],[]),'nose_bottom':([],[]),
                        'mouth_right':([],[]),'mouth_center':([],[]),'mouth_left':([],[]),
                        'left_eye_medial':([],[]),'left_eye_lateral':([],[]),
                        'right_eye_lateral':([],[]),'right_eye_lateral':([],[])}

    featureResultsPopAll = {'right_nouse_lateral':([],[]),'left_nouse_medial':([],[]),'nose_bottom':([],[]),
                            'mouth_right':([],[]),'mouth_center':([],[]),'mouth_left':([],[]),
                            'left_eye_medial':([],[]),'left_eye_lateral':([],[]),
                            'right_eye_lateral':([],[]),'right_eye_lateral':([],[])}    


    colors = {'right_nouse_lateral':(100,100,0),'left_nouse_medial':(255,255,0),'nose_bottom':(175,175,0),
                'mouth_right':(100,0,100),'mouth_center':(175,0,175),'mouth_left':(175,0,175),
                'left_eye_medial':(0,100,0),'left_eye_lateral':(0,255,0),
                'right_eye_lateral':(0,0,100),'right_eye_lateral':(0,0,255)}

    for fname in files:

        print fname
        rslts = "%s\t"%fname
        tmp = os.path.splitext(fname)
        case = int(os.path.basename(tmp[0]))
        dname = tmp[0]+dsuffix
        print fname,os.path.exists(fname),dname,os.path.exists(dname)
        if( os.path.exists(fname) and os.path.exists(dname) ):
            print "processing",fname
            img = cv.LoadImage(fname) # ???Anything else I need to add here
            # Costas treats the images as color, but I need a grayscale image to find max_loc
            minV,maxV,min_loc,max_loc = cv.MinMaxLoc(cv.LoadImage(fname,False))
            im3 = cv.CloneImage(img)			
            im4 = cv.CloneImage(img)
            im5 = cv.CloneImage(img)
            #cv.EqualizeHist(img,im3)
            cv.Circle(im3,max_loc,3,(0,0,0),thickness=-1)
            cv.SaveImage(os.path.join(rdir,"%d_maxloc.png"%(case)),im3)

            #cv.ShowImage('result',im3)
            #cv.WaitKey(0)
            gfeatures = myReadFeatures(dname)
            if(True):#try:
                if(mode == 'nn'):
                    features,ff,offset = gm.matchTheSmartWay2(img,os.path.join('data','features_%03d.data'%case),max_loc,win)
                elif(mode == 'nnpca'):
                    features,ff,offset = gm.matchTheSmartWayPCA(img,os.path.join('data','features_%03d.data'%case),max_loc,win)
                else:
                    features,ff,offset = gm.matchNaive2(img,os.path.join('data','features_%03d.data'%case))
                for i in range(len(features)):
                    # compute difference between detected location and u ser specified location for this case
                    deltaX = abs(int(gfeatures[i][1])-features[i][0])
                    deltaY = abs(int(gfeatures[i][2])-features[i][1])
                    rslts += "%s\t%f\t%f\t"%(ff[i][0],deltaX,deltaY)
                    key = gfeatures[i][0]
                    featureResults[key][0].append(deltaX)
                    featureResults[key][1].append(deltaY)
                    # now compute difference between population location and user specified location for this case
                    # compute difference between detected location and u ser specified location for this case
                    deltaX = abs(int(gfeatures[i][1])-ff[i][1])
                    deltaY = abs(int(gfeatures[i][2])-ff[i][2])
                    key = gfeatures[i][0]
                    featureResultsPopAll[key][0].append(deltaX)
                    featureResultsPopAll[key][1].append(deltaY)
                    if( case not in [22,29] ):
                        featureResultsPop[key][0].append(deltaX)
                        featureResultsPop[key][1].append(deltaY)   

                        clr = colors[key]
                        cv.Circle(im3,features[i],2,clr,thickness=-1)
                        key = ff[i][0]
                        clr = colors[key]
                        cv.Circle(im4,(int(round(ff[i][1])),int(round(ff[i][2]))),2,clr,thickness=-1)
                        cv.Circle(im5,(int(round(ff[i][1]+offset[0])),
                                       int(round(ff[i][2]+offset[1]))),2,clr,thickness=-1)
                cv.SaveImage(os.path.join(rdir,"%d_%s.png"%(case,mode)),im3)    
                print "saving population average overlay to %s"%os.path.join(rdir,"%d_popavg.png"%case) 
                cv.SaveImage(os.path.join(rdir,"%d_popavg.png"%case),im4)
                cv.SaveImage(os.path.join(rdir,"%d_shift_popavg.png"%case),im5)
                f69 = file(os.path.join(rdir,"%d_%s_features.pckle"%(case,mode)),"wb")
                cPickle.dump((features,ff),f69)
                f69.close()
                #raw_input('continue')
                #except Exception, error:
                #print "failed in this case:",error
    fr.write(rslts+"\n")
    keys = featureResults.keys()
    keys.sort()
    
    for k in keys:
        rslts = featureResults[k]
        fr.write("%s\t%f\t%f\n"%(k,np.array(rslts[0]).mean(),np.array(rslts[1]).mean()))

    fr.write("Differences between shifted population averages and specified locations for all cases\n")
    for k in keys:

        rslts = featureResultsPopAll[k]
        fr.write("%s\t%f\t%f\n"%(k,np.array(rslts[0]).mean(),np.array(rslts[1]).mean()))

    fr.write("Differences between shifted population averages and specified locations excluding 22 and 29\n")
    for k in keys:

        rslts = featureResultsPop[k]
        fr.write("%s\t%f\t%f\n"%(k,np.array(rslts[0]).mean(),np.array(rslts[1]).mean()))

    fr.close()

def main():

    parser = getParser()
    (options, args) = parser.parse_args()
    
    if (options.command == 'l'):
        LocateFeatures(options.filename,options.threshold,options.mode)

if __name__ == '__main__':
    main()


